/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { TypeNode, SyntaxKind, TypeReferenceNode } from 'ts-morph';
import { BaseTypeHandler } from './BaseTypeHandler';
import { ITypeHandler, TypeContext, ConversionDirection } from './ITypeHandler';
import {
  PropertyKind,
  TypeStructure,
  SerializerMetadata,
  TypeDependency,
  ClassDetails,
  TypeKind,
  TypeAliasDetails,
  InterfaceDetails
} from '../Types';
import { CustomTypeAnalyzer } from '../analyzers/CustomTypeAnalyzer';
import { ClassAnalyzer } from '../analyzers/ClassAnalyzer';
import { CustomError, ErrorCodes } from '../utils/CustomError';

export class CustomClassHandler extends BaseTypeHandler implements ITypeHandler {
  readonly name = 'CustomClassHandler';
  readonly kind = PropertyKind.OBJECT;
  readonly priority = 10; // 最低优先级，作为fallback

  // ==================== 阶段1: 类型识别 ====================

  matches(typeNode: TypeNode): boolean {
    // 如果是TypeReference且没有被其他Handler处理，就是自定义类
    return typeNode.getKind() === SyntaxKind.TypeReference;
  }

  // ==================== 阶段2: 类型解析 ====================

  parse(typeNode: TypeNode, context: TypeContext): TypeStructure {
    const typeRef = typeNode as TypeReferenceNode;
    const customTypeName = typeRef.getTypeName().getText();
    const typeArgs = typeRef.getTypeArguments();

    // ✅ 递归解析泛型参数
    const { dependencies, parsedArgs } = this.parseGenericArguments(typeArgs, context);

    // ✅ 查找类型定义并收集依赖
    const typeDependency = CustomTypeAnalyzer.getInstance()
      .findDefinition(customTypeName, typeRef.getSourceFile());

    if (!typeDependency) {
      return this.handleMissingTypeDependency(customTypeName);
    }

    // 处理 Type 类型别名：直接使用已解析的类型结构
    if (typeDependency.typeKind === TypeKind.TYPE) {
      return this.handleTypeAlias(typeDependency, typeNode);
    }

    // 计算深度
    const maxArgDepth = parsedArgs.length > 0
      ? Math.max(...parsedArgs.map(arg => arg.depth))
      : 0;

    if (typeDependency.typeKind === TypeKind.INTERFACE) {
      return {
        kind: this.kind,
        depth: parsedArgs.length > 0 ? 1 + maxArgDepth : 0,
        sourceText: typeNode.getText(), // ✅ 使用完整类型文本（包含泛型参数）
        interfaceDetails: typeDependency.details as InterfaceDetails,
        args: parsedArgs, // ✅ 填充泛型参数
        dependencies: [typeDependency, ...dependencies] // ✅ 填充依赖
      };
    } else if (typeDependency.typeKind === TypeKind.CLASS) {
      return {
        kind: this.kind,
        depth: parsedArgs.length > 0 ? 1 + maxArgDepth : 0,
        sourceText: typeNode.getText(), // ✅ 使用完整类型文本（包含泛型参数）
        classDetails: typeDependency.details as ClassDetails,
        args: parsedArgs, // ✅ 填充泛型参数
        dependencies: [typeDependency, ...dependencies] // ✅ 填充依赖
      };
    } else {
      return {
        kind: PropertyKind.UNKNOWN,
        depth: 0,
        sourceText: customTypeName,
        args: [],
        dependencies: []
      };
    }
  }

  private parseGenericArguments(typeArgs: TypeNode[], context: TypeContext): { 
    dependencies: TypeDependency[]; 
    parsedArgs: TypeStructure[] 
  } {
    const dependencies: TypeDependency[] = [];
    const parsedArgs: TypeStructure[] = typeArgs.map(arg => {
      const { TypeHandlerRegistry } = require('./TypeHandlerRegistry');
      const argStructure = TypeHandlerRegistry.getInstance().parseType(arg, {
        ...context,
        depth: context.depth + 1
      });
      dependencies.push(...argStructure.dependencies);
      return argStructure;
    });
    
    return { dependencies, parsedArgs };
  }

  private handleMissingTypeDependency(customTypeName: string): TypeStructure {
    // 未找到类型定义，返回 UNKNOWN 类型结构
    // ClassAnalyzer 会检查是否有 @Transient 注解来决定如何处理
    return {
      kind: PropertyKind.UNKNOWN,
      depth: 0,
      sourceText: customTypeName,
      args: [],
      dependencies: []
    };
  }

  private handleTypeAlias(typeDependency: TypeDependency, typeNode: TypeNode): TypeStructure {
    const typeAliasDetails = typeDependency.details as TypeAliasDetails;

    return {
      ...typeAliasDetails.resolvedType,
      sourceText: typeNode.getText(), // 保留类型别名名称用于生成代码
      dependencies: [typeDependency, ...typeAliasDetails.resolvedType.dependencies]
    };
  }

  // ==================== 阶段3: 序列化器配置 ====================

  getSerializerMetadata(structure: TypeStructure, withParam?: string): SerializerMetadata {
    const serializerName = `${structure.sourceText}Serializer`;
    const defaultInstantiation = this.generateInstantiation(structure);

    return {
      name: serializerName,
      typeDeclaration: this.generateTypeDeclaration(structure, withParam),
      instantiationTemplate: this.applyWithParam(withParam, defaultInstantiation, structure),
      encodeMethod: 'encodeSerializableElement',
      decodeMethod: 'deserialize',
      decoderType: `${structure.sourceText} | undefined`,
      needsTypeAssertion: false
    };
  }

  // ==================== 阶段4: 代码生成 ====================

  generateInstantiation(structure: TypeStructure): string {
    // ✅ 泛型对象：new UserSerializerFactory().getSerializer(T1Serializer, T2Serializer)
    if (structure.args && structure.args.length > 0) {
      const typeName = structure.sourceText.slice(0, structure.sourceText.indexOf('<'));
      const argsSerializers = structure.args.map(arg => {
        const { TypeHandlerRegistry } = require('./TypeHandlerRegistry');
        const handler = TypeHandlerRegistry.getInstance().getHandlerForKind(arg.kind);
        return handler.generateInstantiation(arg);
      });

      return `new ${typeName}SerializerFactory().getSerializer(${argsSerializers.join(', ')})`;
    }

    // ✅ 非泛型对象：UserSerializer.INSTANCE
    const typeName = structure.sourceText;
    return `${typeName}Serializer.INSTANCE`;
  }

  generateTypeDeclaration(structure: TypeStructure, withParam?: string): string {
    // ✅ 泛型对象：Serializer<User<T>>
    if (structure.args && structure.args.length > 0) {
      return `Serializer<${structure.sourceText}>`;
    }

    if (withParam) {
      // ✅ 泛型对象：Serializer<User<T>>
      return `Serializer<${structure.sourceText}>`;
    }

    // ✅ 非泛型对象：UserSerializer
    return `${structure.sourceText}Serializer`;
  }

  generateTypeKey(structure: TypeStructure): string {
    // ✅ 泛型对象：{ classKey: 'User', genericTypes: [T1Key, T2Key] }
    if (structure.args && structure.args.length > 0) {
      const classKey = structure.sourceText.slice(0, structure.sourceText.indexOf('<'));
      const genericKeys = structure.args.map(arg => {
        const { TypeHandlerRegistry } = require('./TypeHandlerRegistry');
        const handler = TypeHandlerRegistry.getInstance().getHandlerForKind(arg.kind);
        return handler.generateTypeKey(arg);
      });

      return `{ classKey: '${classKey}', genericTypes: [${genericKeys.join(', ')}] }`;
    }

    // ✅ 非泛型对象：直接返回类名
    return structure.sourceText;
  }

  // ==================== Sendable转换 ====================

  generateSendableTypeDeclaration(structure: TypeStructure): string {
    // 检查类是否启用了generateSendable
    const classDetails = structure.classDetails;
    if (!classDetails || !classDetails.classDecl) {
      // 没有类声明信息，保持原类型
      return structure.sourceText;
    }

    const classAnalysis = ClassAnalyzer.analyzeClass(classDetails.classDecl);
    if (classAnalysis.decorators.serializable?.generateSendable) {
      // 如果启用了generateSendable，添加Sendable前缀
      const typeName = structure.sourceText;
      if (structure.args && structure.args.length > 0) {
        // 泛型类：User<T> -> SendableUser<T>
        const className = typeName.slice(0, typeName.indexOf('<'));
        const genericPart = typeName.slice(typeName.indexOf('<'));
        return `Sendable${className}${genericPart}`;
      } else {
        // 非泛型类：User -> SendableUser
        return `Sendable${typeName}`;
      }
    }

    // 类装饰器上面没有@Sendable or @Serializable({ generateSendable: true })装饰器
    if (classDetails.classDecl.getDecorator('Sendable')) {
      return structure.sourceText;
    } else {
      throw new CustomError(`Type ${classDetails.classDecl.getName()} is not sendable.
        please add @Sendable or @Serializable({ generateSendable: true })`, ErrorCodes.NOT_SENDABLE);
    }
  }

  generatePropertyConversion(structure: TypeStructure, sourceValue: string, direction: ConversionDirection): string {
    // 检查类是否启用了generateSendable
    const classDetails = structure.classDetails;
    if (!classDetails || !classDetails.classDecl) {
      // 没有类声明信息，直接返回
      return sourceValue;
    }

    const classAnalysis = ClassAnalyzer.analyzeClass(classDetails.classDecl);
    if (classAnalysis.decorators.serializable?.generateSendable) {
      // 启用了generateSendable，需要调用转换方法
      if (direction === ConversionDirection.TO_SENDABLE) {
        // 普通对象 -> Sendable对象：调用toSendable方法
        return `${sourceValue}.toSendable()`;
      } else {
        // Sendable对象 -> 普通对象：调用toOrigin方法
        return `${sourceValue}.toOrigin()`;
      }
    }

    // 未启用generateSendable，直接传递
    return sourceValue;
  }
}

/**
 * 工厂函数
 */
export function createCustomClassHandler(): ITypeHandler {
  return new CustomClassHandler();
}